<template>
  <teleport to="body">
    <transition name="fade"
      ><div class="popover" ref="popover" v-show="modelValue">
        <div class="popover-title disableSelect">{{ title }}</div>
        <div class="popover-content"><slot></slot></div></div
    ></transition>
  </teleport>
</template>

<script lang="ts" setup>
import { nextTick, ref, watch, onBeforeUnmount } from "vue";

const props = withDefaults(
  defineProps<{
    title?: string;
    triggerEle: Array<HTMLElement>;
    modelValue: boolean;
  }>(),
  {
    title: "",
  }
);
const emits = defineEmits<{
  (e: "update:modelValue", show: boolean): void;
}>();

let popover = ref<HTMLDivElement>();

// 更新弹框的位置
const updateDirec: () => void = (): void => {
  const rect = props.triggerEle[0].getBoundingClientRect();
  const top: number = rect?.y! + scrollY;
  const left: number = rect?.x! + scrollX;
  nextTick(() => {
    const selfHei: number = popover.value?.offsetHeight!;
    const selfWid: number = popover.value?.offsetWidth!;
    popover.value!.style.cssText += `top: ${top - selfHei - 10}px;left: ${
      left - selfWid / 2 + rect!.width / 2
    }px`;
  });
};

/**
 * 判断用户所点击的元素是否服务标准
 */
const judgeClick = (e: Event) => {
  const target: HTMLElement = e.target as HTMLElement;
  const editEle: HTMLDivElement = document.getElementsByClassName(
    "message-edit__content"
  )[0] as HTMLDivElement;
  if (
    !props.triggerEle[0].contains(target) &&
    !editEle.contains(target) &&
    !popover.value!.contains(target)
  )
    emits("update:modelValue", false);
};

watch(
  () => props.modelValue,
  (show): void => {
    if (show) {
      updateDirec();
      window.addEventListener("resize", updateDirec);
      document.addEventListener("click", judgeClick);
    } else {
      window.removeEventListener("resize", updateDirec);
      document.removeEventListener("click", judgeClick);
    }
  }
);

onBeforeUnmount(() => window.removeEventListener("resize", updateDirec));
</script>

<style lang="scss" scoped>
.fade {
  @include fade(0.2s, ease-in-out);
}
.popover {
  background-color: #fff;
  position: absolute;
  @include setWidHei(450px, 360px);
  box: {
    sizing: border-box;
    shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
  }
  padding: 0 12px 12px;
  border: 1px solid #e4e7ed {
    radius: 3px;
  }

  &-title {
    padding: 12px 0 12px 16px;
  }

  &-content {
    height: 303px;
    box-sizing: border-box;
  }

  &::after {
    content: "";
    position: absolute;
    top: 355px;
    left: 49%;
    transform: translateX(-50%);
    transform: rotate(45deg);
    box-sizing: border-box;
    background-color: #fff;
    border: {
      right: 1px solid #e4e7ed;
      bottom: 1px solid #e4e7ed;
    }
    @include setWidHei(8px, 8px);
  }
}
</style>
